#include <system.h>

/* Define an IDT entry */
struct idt_entry
{
	unsigned short base_lo;
	unsigned short sel;		/* Kernel segment goes here */
	unsigned char always0;		/* always 0 */
	unsigned char flags;		/* Set using the above table */
	unsigned short base_hi;
} __attribute__((packed));

struct idt_ptr
{
	unsigned short limit;
	unsigned int base;
} __attribute__((packed));

/* Declare an IDT of 256 engtries. We only use the first 32 entries.
 * If an undefined IDT entry is hit, it will cause an "Unhandled Interrupt" exception 
 * Any descriptor for which 'presence' bit is cleared (0) will generate the same */
struct idt_entry idt[256];
struct idt_ptr idtp;

/* in 'start.asm', used to load our IDT */
extern void idt_load();

/* Set an entry in the IDT. */
void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags)
{
	idt[num].base_lo = (base & 0xFFFF);
	idt[num].base_hi = (base >> 16) & 0xFFFF;

	idt[num].sel = sel;
	idt[num].always0 = 0;
	idt[num].flags = flags;
}

void idt_install()
{
	idtp.limit = (sizeof(struct idt_entry) * 256) - 1;
	idtp.base = &idt;

	memset(&idt, 0, sizeof(struct idt_entry) * 256);

	/* Add any new ISRs to the IDT here using idt_set_gate */
	
	idt_load();
}
